home *** CD-ROM | disk | FTP | other *** search
/ AOL File Library: 9,300 to 9,399 / 9300.zip / AOLDLs / HTML & Web Tools (MAC) / WEB_ Print2Pict 3.7.1 / Print2Pict 3.7.1Ä.sit / Print2Pict 3.7.1ƒ / Sourcesƒ / P2PX_PICS.c < prev    next >
C/C++ Source or Header  |  1996-04-27  |  14KB  |  658 lines

  1. /*====================
  2.  
  3.     Print to PICS. ⌐ B.Raoult 1992
  4.     
  5.     This file contains an example of a Print2Pict 3.0 extension.
  6.     It saves printed pages in a PICS file.
  7.  
  8. ====================*/
  9. #include "P2PX.h"
  10. #include "tools.h"
  11.  
  12. #ifndef __MEMORY__
  13. #    include <Memory.h>
  14. #endif
  15.  
  16. #ifndef __RESOURCES__
  17. #    include <Resources.h>
  18. #endif
  19.  
  20. #ifndef __ERRORS__
  21. #    include <Errors.h>
  22. #endif
  23.  
  24. #ifndef __QUICKDRAW__
  25. #    include <Quickdraw.h>
  26. #endif
  27.  
  28. #ifndef __TOOLUTILS__
  29. #    include <ToolUtils.h>
  30. #endif
  31.  
  32. #ifndef __A4STUFF__
  33. #    include <A4Stuff.h>
  34. #endif
  35.  
  36. #define    TRUE        true
  37. #define FALSE        false
  38.  
  39. #define OPTS        'OPTS'        /* Type of our options resource                        */
  40. #define OPTS_ID        128            /* ID of our options resource                        */
  41.  
  42. #define SPEED    2            /* Frames/Seconds input field in the options dialog */
  43. #define DELETE    3            /* Frames/Seconds input field in the options dialog */
  44. #define MOVIE    4
  45.  
  46. #define FIRST_FRAME            128
  47. #define LAST_FRAME            163
  48.  
  49. /*=======
  50.  
  51.     Prototypes 
  52.     
  53. =======*/
  54.  
  55. OSErr    GetFlags(P2PXPtr arg);
  56. OSErr    DoInit(P2PXPtr arg);
  57. OSErr    DoEnd(P2PXPtr arg);
  58. OSErr    DoPutPage(P2PXPtr arg);
  59. OSErr    DoOptOpen(P2PXPtr arg);
  60. OSErr    DoOptEvent(P2PXPtr arg);
  61. OSErr    DoOptItem(P2PXPtr arg);
  62. OSErr    DoOptDone(P2PXPtr arg);
  63.  
  64. /*=======
  65.  
  66.     Structure of INFO resource used in PICS files 
  67.  
  68. =======*/
  69.  
  70. typedef struct {
  71.  
  72.     short    color;            /* Color picture             */
  73.     short    depth;            /* Depth of picture         */
  74.     short    speed;            /* Frames/seconds             */
  75.     short    version;        /* version                     */
  76.     OSType    creator;        /* creator                     */
  77.     long    maxsize;        /* size of largest picture    */
  78.     
  79. } Infos, *PInfos, **HInfos;
  80.  
  81. /*=======
  82.  
  83.     Private data 
  84.     
  85. ========*/
  86.  
  87. typedef struct {
  88.  
  89.     short    resfile;        /* reference number of the PICS file */
  90.     short     count;            /* current image number              */
  91.     HInfos    info;            /* Handle to info resource           */
  92.     FSSpec    fspec;            /* Specs of the PICS file             */
  93.     
  94. } Globals, *PGlobals, **HGlobals;
  95.  
  96. /*========
  97.  
  98.     Our options
  99.     
  100. ========*/
  101.  
  102. typedef struct {
  103.  
  104.     short    speed;            /* Frames/seconds                             */
  105.     Boolean remove;            /* Delete file if the user aborts the job    */
  106.     
  107. } Opts, *POpts, **HOpts;
  108.  
  109. /*========
  110.  
  111.     Data for animation
  112.     
  113. ========*/
  114.  
  115. typedef struct {
  116.  
  117.     short        frame;            /* Current frame                             */
  118.     long           last;            /* last time we draw a frame                */
  119.     Boolean       ready;            /* ready after first update                  */
  120.     Boolean        color;            /* plot 'cicn'                                */
  121.     Rect        box;            /* Where to draw the frames                    */
  122.     long        speed;            /* Speed in 60th of seconds                    */
  123.     
  124. } Anim, *PAnim, **HAnim;
  125.  
  126.  
  127. /*=======
  128.  
  129.     Usefull macro to access our globals
  130.     
  131. ========*/
  132.  
  133. #define G    (**((HGlobals)(arg->data)))
  134. #define A    (**((HAnim)(arg->data)))
  135. #define O    (**o)
  136. #define I    (**info)
  137.  
  138. /*======================================================================================
  139.  
  140.     This is the entry point of the code resource.
  141.     It simply dispatches the calls to the proper routine
  142.     
  143. ======================================================================================*/
  144.  
  145. pascal    OSErr main(int msg,P2PXPtr arg)
  146. {
  147.     int ret = noErr;
  148.     
  149.     EnterCodeResource();
  150.     
  151.     switch (msg)
  152.     {
  153.         case kGetFlagsMsg:
  154.             ret = GetFlags(arg);
  155.             break;
  156.             
  157.         case kInitMsg:
  158.             ret = DoInit(arg);
  159.             break;
  160.             
  161.         case kEndMsg:
  162.             ret = DoEnd(arg);
  163.             break;
  164.  
  165.         case kPutPageMsg:
  166.             ret = DoPutPage(arg);
  167.             break;
  168.             
  169.         case kOptOpenMsg:
  170.             ret = DoOptOpen(arg);
  171.             break;
  172.             
  173.         case kOptEventMsg:
  174.             ret = DoOptEvent(arg);
  175.             break;
  176.             
  177.         case kOptItemMsg:
  178.             ret = DoOptItem(arg);
  179.             break;
  180.             
  181.         case kOptDoneMsg:
  182.             ret = DoOptDone(arg);
  183.             break;
  184.  
  185.  
  186.     }
  187.     
  188.     ExitCodeResource();
  189.     
  190.     return ret;
  191. }
  192.  
  193. /*======================================================================================
  194.  
  195.     Get flags of the code resource.
  196.     
  197. - It can be called at ANY TIME. 
  198.     
  199. - Most of the fields of the parameters will not be valid.
  200.   However, unintialized fields will contain nulls.
  201.     
  202. - Note that you can later change the values of the flags
  203.   in any other calls.
  204.     
  205. ======================================================================================*/
  206.  
  207. OSErr GetFlags(P2PXPtr arg)
  208. {
  209.     arg->flags = 
  210.         kCanPreview         + /* Preview is OK                        */
  211.         kEnvironmentOk         + /* We can run on all Macs             */
  212.         kWantFileNames        + /* Wants the file names to save pages */
  213.         kHasOwnOptions        ; /* We have some options               */
  214.     
  215.     return noErr;
  216. }
  217.  
  218. /*======================================================================================
  219.  
  220.     Called when the application calls PrOpenDoc().
  221.     We allocate the handles needed for our globals.
  222.     
  223. ======================================================================================*/
  224.  
  225. OSErr    DoInit(P2PXPtr arg)
  226. {
  227.     HInfos info;
  228.     HOpts  o;
  229.     
  230.     /* Allocate some space four our globals */
  231.     
  232.     if(!(arg->data = NewHandleClear(sizeof(Globals)))) 
  233.         return iMemFullErr;
  234.         
  235.         
  236.     /* Allocate some space for the INFO structure */
  237.         
  238.     if(!(info = (HInfos)NewHandleClear(sizeof(Infos))))
  239.         return iMemFullErr;
  240.         
  241.     /* Get our options */
  242.         
  243.     if(!(o = (HOpts)GetResource(OPTS,OPTS_ID)))
  244.         return ResError();
  245.  
  246.     
  247.     G.resfile    = -1;        /* The PICS file is not yet opened                 */
  248.     G.count        = 128;        /* PICT resources start from 128 in a PICS file */
  249.     G.info        = info;        /* Save the INFO structure                      */
  250.     
  251.     I.maxsize = 0;                /* No pictures yet                    */
  252.     I.creator = arg->creator;    /* Use the creator chosen by the user */
  253.     I.speed   = O.speed;        /* Use the speed chosen by the use    */
  254.     
  255.     return noErr; /* All OK... */
  256. }
  257.  
  258. /*======================================================================================
  259.  
  260.     End of print. Called from PrOpenDoc() if everything OK.
  261.     Can be called at any time if something went wrong, so 
  262.     check if the private data is valid.
  263.  
  264. ======================================================================================*/
  265.  
  266.  
  267. OSErr    DoEnd(P2PXPtr arg)
  268. {
  269.     int     save     = CurResFile();                 /* Save the current resource file */
  270.     OSErr    retCode = noErr;                        /* be optimistic                  */
  271.     HOpts   o = (HOpts)GetResource(OPTS,OPTS_ID);    /* Get our options record         */
  272.     Boolean ok = TRUE;                                /* If not, remove the file        */
  273.     
  274.     if(arg->data)                    /* Did we have memory ?    */
  275.     {
  276.         HInfos info = G.info;        /* Recover the INFO structure */
  277.         
  278.         if(G.resfile != -1)            /* Did we open any files ? */
  279.         {
  280.             UseResFile(G.resfile);
  281.             
  282.             if((arg->error == noErr) && info)
  283.             {
  284.             
  285.                 /* Add the INFO resource to the PICS file, check for error */
  286.                 
  287.                 AddResource ((Handle) info,'INFO',128,"\p");    retCode = retCode?retCode:ResError();
  288.                 WriteResource((Handle) info);                    retCode = retCode?retCode:ResError();
  289.                 UpdateResFile(G.resfile);                        retCode = retCode?retCode:ResError();
  290.                 
  291.             }
  292.             
  293.             if(retCode != noErr)
  294.                 ok = FALSE;
  295.             
  296.         }
  297.         CloseResFile(G.resfile);
  298.         
  299.         
  300.         /* Now let's do some clean up */
  301.         
  302.         if(info)
  303.             DisposHandle((Handle) info);
  304.             
  305.         /* If an error was reported, we need to remove the file */
  306.         
  307.         if(arg->error != iPrAbort && arg->error != noErr)
  308.             ok = FALSE;
  309.             
  310.         /* If this error is iPrAbort (user cancel) remove the file
  311.            according to the options */
  312.            
  313.         if(o && O.remove)
  314.             if(arg->error == iPrAbort)
  315.                 ok = FALSE;
  316.             
  317.         /* If something went wrong, don't leave incomplete files around */
  318.                         
  319.         if(!ok)
  320.             FSpDelete(&arg->fspec);
  321.             
  322.         DisposHandle(arg->data);
  323.  
  324.     }
  325.     
  326.     /* Restore current resource file */
  327.     UseResFile(save);
  328.     
  329.     return retCode;
  330. }
  331.  
  332. /*======================================================================================
  333.  
  334.     Process a page. Called when the application calls PrClosePage().
  335.     Create the PICS file if it is the first time in.
  336.     Add the picture as a PICT resource.
  337.     
  338. ======================================================================================*/
  339.  
  340. OSErr DoPutPage(P2PXPtr arg)
  341. {
  342.     int save = CurResFile();
  343.     OSErr retCode = noErr;
  344.     HInfos info;
  345.  
  346.     /* No luck... */
  347.     
  348.     if(!(arg->data)) 
  349.         return -1;
  350.         
  351.     if(!(arg->pict)) 
  352.         return -1;
  353.     
  354.     info = G.info;
  355.         
  356.     /* First time in */
  357.     
  358.     if(G.resfile == -1)
  359.     {
  360.             
  361.         /* Delete previous file if any */
  362.  
  363.         if( (retCode = FSpDelete(&arg->fspec)) != noErr)
  364.             if(retCode != fnfErr) 
  365.                 return retCode;
  366.  
  367.         /* Create the file, giving it the right Creator and File type.*/
  368.         
  369.         FSpCreateResFile(&arg->fspec, arg->creator, 'PICS',arg->script);
  370.         if ((retCode = ResError()) != noErr )
  371.             return retCode;
  372.  
  373.         /* Save the file spec if we need to remove it later */
  374.         
  375.         G.fspec = arg->fspec;
  376.         
  377.         /* Open the resoure file */
  378.         
  379.         G.resfile = FSpOpenResFile(&arg->fspec,fsRdWrPerm);
  380.         if(G.resfile == -1) 
  381.             return ResError();
  382.         
  383.         /* We don't want any more file names */
  384.         
  385.         arg->flags &= ~kWantFileNames;
  386.         
  387.         /* Fill the rest of the INFO structure */
  388.         
  389.         /* Are the PICTs in color ? */
  390.         
  391.         I.color = arg->color;
  392.         
  393.         /* If yes, get the depth of the printing port */
  394.         if(arg->color)
  395.         {
  396.             PixMapHandle pix = ((CGrafPtr)(arg->port))->portPixMap;
  397.             I.depth = (**pix).pixelSize;
  398.         }
  399.         else
  400.             I.depth = 1;
  401.     }
  402.         
  403.     
  404.     /* Now save the current page as a PICT resource */
  405.     
  406.     UseResFile(G.resfile);
  407.         
  408.     AddResource((Handle) arg->pict,'PICT',(G.count)++,"\p");    retCode = retCode?retCode:ResError();
  409.     SetResAttrs((Handle) arg->pict,resPurgeable);                retCode = retCode?retCode:ResError();
  410.     ChangedResource((Handle) arg->pict);                        retCode = retCode?retCode:ResError();
  411.     WriteResource((Handle) arg->pict);                            retCode = retCode?retCode:ResError();
  412.     UpdateResFile(G.resfile);                                    retCode = retCode?retCode:ResError();
  413.  
  414.     /* Detache it so Print2Pict can kill it */
  415.     
  416.     DetachResource((Handle) arg->pict);
  417.         
  418.     /* Update maxsize in INFO structure */
  419.     
  420.     if(GetHandleSize((Handle) arg->pict)>I.maxsize)
  421.         I.maxsize = GetHandleSize((Handle) arg->pict);
  422.         
  423.     /* Restore current resource file */
  424.     
  425.     UseResFile(save);
  426.         
  427.     return retCode;
  428.  
  429. }
  430.  
  431. /*======================================================================================
  432.     
  433.     Initialize the options dialog. Allocate some memory for the animation,
  434.     initialize the dialog items.
  435.  
  436. ======================================================================================*/
  437.  
  438. OSErr    DoOptOpen(P2PXPtr arg)
  439. {
  440.     HOpts   o = (HOpts)GetResource(OPTS,OPTS_ID);    /* Get our options record */
  441.     HAnim     a;
  442.     
  443.     /* Something went wrong */
  444.     
  445.     if(!o)
  446.         return ResError();
  447.     
  448.     /* Set the frames/seconds text field */
  449.     
  450.     if(O.speed <1 )
  451.         O.speed = 1;
  452.     
  453.     
  454.     /* Initalize the dialog items, Remember to skip the Print2Pict items */
  455.     
  456.     Long2Dialog(arg->dlog,arg->skip + SPEED,(long)O.speed);
  457.     SetCheck(arg->dlog,arg->skip + DELETE,O.remove);
  458.     
  459.     /* Allocate some private storage for the animation */
  460.     
  461.     a = (HAnim)NewHandleClear(sizeof(Anim));
  462.     
  463.     /* No big deal if not enough memory */
  464.     
  465.     if(a)
  466.     {
  467.         /* Store the handle in the parameter block */
  468.         
  469.         arg->data = (Handle)a;
  470.         
  471.         /* Save the rectangle for the animation */
  472.         
  473.         A.box   = GetItemR(arg->dlog,arg->skip + MOVIE);
  474.         
  475.         A.frame = FIRST_FRAME;
  476.         A.speed = 60 / O.speed; /* Time between frams in 60th of seconds */
  477.         A.color = HasColor();    /* Color QuickDraw is there...           */
  478.     }
  479.  
  480.     return noErr;
  481.     
  482.     
  483. }
  484.  
  485. /*======================================================================================
  486.  
  487.     Called from the ModalDialog filter procedure. We handle use the null events
  488.     to run the animation.
  489.  
  490. ======================================================================================*/
  491.  
  492. OSErr    DoOptEvent(P2PXPtr arg)
  493. {
  494.     Rect r;
  495.     
  496.     if(arg->data)
  497.     {
  498.         switch(arg->event->what)
  499.         {
  500.             
  501.             case updateEvt:
  502.             
  503.                 if(arg->event->message == (long)arg->dlog)
  504.                 {
  505.                     /* wait first update before starting the animation */
  506.                     
  507.                     A.ready = TRUE;
  508.                     
  509.                     /* Draw a frame around the rectangle */
  510.                     
  511.                     r = A.box;
  512.                     InsetRect(&r,-1,-1);
  513.                     FrameRect(&r);
  514.                 }
  515.                 
  516.                 break;
  517.                 
  518.             case nullEvent:
  519.             
  520.                 if(A.ready)
  521.                 {
  522.                     long now = TickCount();
  523.                     Rect      r;
  524.                     CIconHandle    h;
  525.                     
  526.                     /* If the time is elapsed */
  527.                     
  528.                     if( now-A.last >= A.speed)
  529.                     {
  530.                         A.last = now;
  531.                         r= A.box;
  532.                         
  533.                         /* Plot cicn if ColorQD is available, otherwise plot ICON */
  534.                         
  535.                         if(A.color)
  536.                         {
  537.                             h = GetCIcon(A.frame);
  538.                             PlotCIcon(&r,h);
  539.                             DisposCIcon(h);
  540.                         }
  541.                         else
  542.                             PlotIcon(&r,GetIcon(A.frame));
  543.  
  544.                         
  545.                         /* Move to next frame */
  546.                         
  547.                         A.frame++;
  548.                         
  549.                         if(A.frame>LAST_FRAME)
  550.                             A.frame = FIRST_FRAME;
  551.                     }
  552.                 }
  553.                 break;
  554.         }
  555.     }
  556.     
  557.     return noErr;
  558. }
  559.  
  560. /*======================================================================================
  561.  
  562.     Called with the item returned by ModalDialog.
  563.  
  564. ======================================================================================*/
  565.  
  566.  
  567. OSErr    DoOptItem(P2PXPtr arg)
  568. {
  569.     long    speed;
  570.  
  571.     switch(arg->item - arg->skip)
  572.     {
  573.         /* Click in the "delete" checkbox */
  574.         
  575.         case DELETE:
  576.             ClickCheck(arg->dlog,arg->item);
  577.             break;
  578.             
  579.         /* The "speed" text field as been modified */
  580.         
  581.         case SPEED:
  582.         
  583.             speed = Dialog2Long(arg->dlog,arg->item);
  584.             
  585.             if(speed<1)
  586.                 speed = 1;
  587.                 
  588.             /* Change the speed of the animation with the new value */
  589.             
  590.             if(arg->data)
  591.                 A.speed = 60/speed;
  592.                 
  593.             break;
  594.     }
  595.     
  596.     return noErr;
  597. }
  598.  
  599. /*======================================================================================
  600.  
  601.     End of option dialog. Release use memory and save the changes.
  602.  
  603. ======================================================================================*/
  604.  
  605. OSErr    DoOptDone(P2PXPtr arg)
  606. {
  607.     HOpts   o = (HOpts)GetResource(OPTS,OPTS_ID);    /* Get our options record */
  608.     long    newspeed;
  609.     Boolean remove;
  610.     OSErr    retCode = noErr;
  611.     
  612.     /* Something went wrong */
  613.  
  614.     if(!o)
  615.     {
  616.         if(arg->data)
  617.             DisposHandle(arg->data);
  618.         return ResError();
  619.     }
  620.         
  621.     /* Get the new values */
  622.     
  623.     newspeed = Dialog2Long(arg->dlog,arg->skip + SPEED);
  624.     remove   = GetCheck(arg->dlog,arg->skip + DELETE);
  625.     
  626.     /* If the user changed the value, update the record */
  627.     
  628.     if(O.speed != newspeed || O.remove != remove)
  629.     {
  630.         if(newspeed <1 )
  631.             newspeed = 1;
  632.  
  633.         O.speed = newspeed;
  634.         O.remove = remove;
  635.         ChangedResource((Handle) o);
  636.         WriteResource((Handle) o);
  637.         UpdateResFile(HomeResFile((Handle) o));
  638.         retCode =  ResError();
  639.     }
  640.     
  641.     /* Realease used memory */
  642.     if(arg->data)
  643.     {
  644.         /* Because we draw outside of an item, we must clear it ourselves */
  645.         
  646.         Rect r = A.box;
  647.         InsetRect(&r,-1,-1);
  648.         EraseRect(&r);
  649.  
  650.         DisposHandle(arg->data);
  651.     }
  652.     
  653.     return retCode;
  654. }
  655.  
  656.  
  657.  
  658.